package com.javawork.juc.four;

import java.util.concurrent.TimeUnit;

/**
 * @author zhangxiaolu
 * @since 2023-02-11 17:42
 */
public class VolatileAtomicDemo {

    public static void main(String[] args) {
        MyNumber myNumber = new MyNumber();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                for (int j = 0; j <1000; j++) {
                    myNumber.addNumber();
                }
            }, String.valueOf(i)).start();
        }

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(myNumber.number);
    }
}

class MyNumber {

    /**
     * 对于volatile变量具备可见性，JVM只是保证从主内存加载到线程工作内存的值是最新的，也仅是数据加载时是最新的。但是多线程环境下，“数据计算”和
     * ”数据赋值”操作可能多次出现，若数据在加载之后，若主内存volatile修饰变量发生修改之后，线程工作内存中的操作将会作废去读主内存最新值，
     * 操作出现写丢失问题。即各线程私有内存和主内存公共内存中变量不同步，进而导致数据不一致。由此可见volatile解决的是变量读时的可见性问题，
     * 但无法保证原子性，对于多线程修改主内存共享变量的场景必须使用加锁同步。
     */
    volatile int number;

//    public synchronized void addNumber() {
//        number++;
//    }

    public void addNumber() {
        number++;
    }
}